package it.lorenz.server.fk.business.jr;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.util.JRSaver;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import org.springframework.stereotype.Component;

@Component("jasperReportsManager")
public class JasperReportsManager {

    private File pathToTemplatesDir;

    public JasperReportsManager(String pathToTemplatesDir)
       throws JasperReportsException {
        setPathToTemplatesDir(pathToTemplatesDir);
    }

    public JasperDesign loadJRXML(String path) throws JasperReportsException {
        return loadJRXML(new File(path));
    }

    public JasperDesign loadJRXML(File file) throws JasperReportsException {
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);
            return loadJRXML(in);
        } catch (Exception e) {
            throw new JasperReportsException(e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public JasperDesign loadJRXML(InputStream in) throws JasperReportsException {
        try {
            return JRXmlLoader.load(in);
        } catch (JRException e) {
            throw new JasperReportsException(e);
        }
    }

    public JasperReport compile(JasperDesign jasperDesign)
       throws JasperReportsException {
        try {
            return JasperCompileManager.compileReport(jasperDesign);
        } catch (JRException e) {
            throw new JasperReportsException(e);
        }
    }

    public void saveTemplate(String path, JasperReport report)
       throws JasperReportsException {
        saveTemplate(new File(path), report);
    }

    public void saveTemplate(File file, JasperReport report)
       throws JasperReportsException {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(file);
            saveTemplate(out, report);
        } catch (Exception e) {
            throw new JasperReportsException(e);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public void saveTemplate(OutputStream out, JasperReport report)
       throws JasperReportsException {
        try {
            JRSaver.saveObject(report, out);
        } catch (JRException e) {
            throw new JasperReportsException(e);
        }
    }

    public JasperReport loadTemplate(String path) throws JasperReportsException {
        return loadTemplate(new File(pathToTemplatesDir, path));
    }

    public JasperReport loadTemplate(File file) throws JasperReportsException {
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);
            return loadTemplate(in);
        } catch (Exception e) {
            throw new JasperReportsException(e);
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public JasperReport loadTemplate(InputStream in)
       throws JasperReportsException {
        try {
            return (JasperReport) JRLoader.loadObject(in);
        } catch (JRException e) {
            throw new JasperReportsException(e);
        }
    }

    public JasperPrint fillReport(JasperReport report,
       Map<String, Object> attributes, JRDataSource dataSource)
       throws JasperReportsException {
        try {
            return JasperFillManager.fillReport(report, attributes, dataSource);
        } catch (JRException e) {
            throw new JasperReportsException(e);
        }
    }

    public void exportToPDF(JasperPrint print, OutputStream out)
       throws JasperReportsException {
        try {
            JasperExportManager.exportReportToPdfStream(print, out);
        } catch (JRException e) {
            throw new JasperReportsException(e);
        }
    }

    public void exportToXML(JasperPrint print, OutputStream out)
       throws JasperReportsException {
        try {
            JasperExportManager.exportReportToXmlStream(print, out);
        } catch (JRException e) {
            throw new JasperReportsException(e);
        }
    }

    public File getPathToTemplatesDir() {
        return pathToTemplatesDir;
    }

    public void setPathToTemplatesDir(File pathToTemplatesDir)
       throws JasperReportsException {
        if (!pathToTemplatesDir.isDirectory()) {
            pathToTemplatesDir = new File(new File(System
               .getProperty("user.dir")), pathToTemplatesDir.getPath());
            if (!pathToTemplatesDir.isDirectory()) {
                throw new JasperReportsException(String.format(
                   "Configuration Error: %s doesn't exist!",
                   pathToTemplatesDir));
            } else {
                this.pathToTemplatesDir = pathToTemplatesDir;
            }
        } else {
            this.pathToTemplatesDir = pathToTemplatesDir;
        }
    }

    final public void setPathToTemplatesDir(String pathToTemplatesDir)
       throws JasperReportsException {
        setPathToTemplatesDir(new File(pathToTemplatesDir));
    }
}
